﻿using FairyGUI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using LuaInterface;
using TMPro;

namespace YanhuaMMO
{
    public class LanguageManager : Manager
    {
        public static LanguageManager Instance;

        private GameManager gameMgr;
        private bool menuInitialied = false;

        private void Awake()
        {
            Instance = this;
        }

        private void Start()
        {
            DontDestroyOnLoad(gameObject);
            StartCoroutine(InitLanguage());
        }


        private IEnumerator InitLanguage()
        {

            if (AppConst.LanguageMode)
            {
                DontDestroyOnLoad(gameObject);
                LanguageType type = (LanguageType)PlayerPrefs.GetInt("Language_Type", 0);

                if (type != AppConst.DefalutLanguageType)
                {
                    string end_str = MulLanguageUtil.GetBranchEndString(type);

                    string urlpath = AppConst.BranchUrl + end_str.ToLower() + "/" + end_str.ToLower() + "_files.txt";
                    yield return DownLoadFilesMenu(type);
                   
                    if (CheckResourcesIntegrity(type))
                    {
                        ChangeLanguage(type);
                    }
                    else
                    {
                        yield return DownLoadFUIBranchRes(type, false);
                    }
                }
            }
        }    

        public static LanguageManager GetLanguageManager()
        {
            return Instance;
        }

        private LanguageType _language;

        public LanguageType language
        {
            get
            {
                int type = PlayerPrefs.GetInt("Language_Type", 0);
                if (_language != (LanguageType)type)
                {
                    _language = (LanguageType)type;
                }
                   
                return (LanguageType)type;
            }
            set
            {
                if (_language != value)
                {
                    PlayerPrefs.SetInt("Language_Type", (int)value);
                }
                StartCoroutine(DownLoadFilesMenu(value));
                _language = value;
            }
        }

        private static Dictionary<string, string[]> cache_bundle = new Dictionary<string, string[]>();
        private void InitialiedMenu(LanguageType type)
        {
            if (menuInitialied)
            {
                return;
            }
            cache_bundle.Clear();
            string path = Util.DataPath + "FuiBranch/" + MulLanguageUtil.GetBranchEndString(type).ToLower() + "_files.txt";//清单
            if (File.Exists(path))
            {
                float size = 0;
                var files = File.ReadAllLines(path);
                for (int i = 0; i < files.Length; i++)
                {
                    var arr = files[i].Split('|');
                    if (!cache_bundle.ContainsKey(arr[0]))
                    {
                        cache_bundle.Add(arr[0], arr);
                        size += float.Parse(arr[2]);
                    }
                    else
                    {
                        Util.Log("资源已存在：" + arr[0]);
                    }
                }
                menuInitialied = true;
            }
        }

        /// <summary>
        /// 下载分支的资源清单
        /// </summary>
        /// <returns></returns>
        public IEnumerator DownLoadFilesMenu(LanguageType type)
        {
            if (type == LanguageType.Chinese)
                yield break;
            Util.Log("开始下载分支资源清单");
            string end_str = MulLanguageUtil.GetBranchEndString(type);
            string path = Util.DataPath + "FuiBranch/"  + end_str.ToLower() + "_files.txt";//清单
            if (!File.Exists(path))
            {
                string urlpath = AppConst.BranchUrl + end_str.ToLower() + "/" + end_str.ToLower() + "_files.txt";
                yield return GetGameManager().DownLoadFile(urlpath, path);
                InitialiedMenu(type);
            }
            else
            {
                string urlpath = AppConst.BranchUrl + end_str.ToLower() + "/" + end_str.ToLower() + "_files.txt";
                yield return GetGameManager().DownLoadFile(urlpath, path);
                InitialiedMenu(type);
            }
        }

        private GameManager GetGameManager()
        {
            if (gameMgr == null)
                gameMgr = AppFacade.Instance.GetManager<GameManager>(ManagerName.Game);
            return gameMgr;
        }

        /// <summary>
        /// 切换分支
        /// </summary>
        /// <param name="type"></param>
        public void ChangeLanguage(LanguageType type)
        {
            language = type;

            if (type != LanguageType.Chinese)
            {
                InitialiedMenu(type);
                if (CheckResourcesIntegrity(type))
                {
                    string endstr = MulLanguageUtil.GetBranchEndString(type).ToLower();
                    string fileContent;
                    string path = MulLanguageUtil.GetLocalAssetsPath(type) + "font_" + endstr + ".xml";//清单
                    if (File.Exists(path))
                    {
                        using (StreamReader sread = new StreamReader(path, Encoding.UTF8))
                        {
                            fileContent = sread.ReadToEnd();

                            FairyGUI.Utils.XML xml = new FairyGUI.Utils.XML(fileContent);
                            UIPackage.SetStringsSource(xml);
                        }
                    }
                    else
                    {
                        Util.LogError("FUI组件文本xml未找到！");
                    }
                    

                    UIPackage.branch = MulLanguageUtil.GetBranchEndString(type);
#if UNITY_EDITOR && !CLIENT_BUNDLE
                    string fontpath = "Assets/ReplaceResources/Fonts/tc/GoogleSiYuan_Heavy.asset";
                    var asset = UnityEditor.AssetDatabase.LoadAssetAtPath(fontpath, typeof(TMP_FontAsset));
#else
                    string fontpath = MulLanguageUtil.GetLocalAssetsPath(type) + "GoogleSiYuan_Heavy.asset";
                    var bundle = AssetBundle.LoadFromFile(MulLanguageUtil.GetLocalAssetsPath(type) + "font/tc_font.unity3d" );
                    var asset = bundle.LoadAsset<TMP_FontAsset>("GoogleSiYuan_Heavy.asset");
#endif
                    string name = "GoogleSiYuan_Heavy";
                    // object asset = Resources.Load("Fonts/tc/" + name);
                    if (asset != null)
                    {
                        TMPFont font = new TMPFont();
                        font.name = name;
                        ((TMPFont)font).fontAsset = (TMPro.TMP_FontAsset)asset;
                        FontManager.RegisterFont(font);
                    }
                }
                else
                {
                    LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                    if (luaTable != null)
                    {
                        Util.CallDisposeMethod("LanguageManager", "ShowAssetsDeficiencyTips");
                        luaTable.Dispose();
                    }
                }
                menuInitialied = false;
            }
            else
            {
                FairyGUI.Utils.XML xml = new FairyGUI.Utils.XML("");
                UIPackage.SetStringsSource(xml);
                UIPackage.branch = MulLanguageUtil.GetBranchEndString(type);

                var asset = Resources.Load("Fonts/GoogleSiYuan_Heavy");
                string name = "GoogleSiYuan_Heavy";
                // object asset = Resources.Load("Fonts/tc/" + name);
                if (asset != null)
                {
                    TMPFont font = new TMPFont();
                    font.name = name;
                    ((TMPFont)font).fontAsset = (TMPro.TMP_FontAsset)asset;
                    FontManager.RegisterFont(font);
                }
                menuInitialied = false;
            }
        }

        public void ShowAssetsSizeTip(LanguageType type)
        {
            StartCoroutine(GetAssetsSize(type));
        }

        public IEnumerator GetAssetsSize(LanguageType type)
        {
            yield return DownLoadFilesMenu(type);
            string end_str = MulLanguageUtil.GetBranchEndString(type);

            string path = Util.DataPath + "FuiBranch/" + end_str.ToLower() + "_files.txt";//清单
            float size = 0;

            if (CheckResourcesIntegrity(type))
            {
                LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                if (luaTable != null)
                {
                    Util.CallDisposeMethod("LanguageManager", "DoChangeLanguage", size);
                    luaTable.Dispose();
                }
            }
            else
            {
                if (File.Exists(path))
                {
                    var files = File.ReadAllLines(path);
                    for (int i = 0; i < files.Length; i++)
                    {
                        var arr = files[i].Split('|');
                        string localpath = MulLanguageUtil.GetLocalAssetsPath(type) + arr[3] + "/" + arr[0];
                        if (File.Exists(localpath))
                        {
                            string localMd5 = Util.md5file(localpath);
                            if (localMd5 != arr[1])
                            {
                                size += float.Parse(arr[2]);
                            }
                        }
                        else
                        {
                            size += float.Parse(arr[2]);
                        }
                    }
                    //resCount = size;
                }

                LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                if (luaTable != null)
                {
                    Util.CallDisposeMethod("LanguageManager", "ShowDownloadTips", size);
                    luaTable.Dispose();
                }
            }
        }

        /// <summary>
        /// 检测分支资源是否完整
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool CheckResourcesIntegrity(LanguageType type)
        {
            List<string[]> ls_needDownFiles = new List<string[]>();
            string end_str = MulLanguageUtil.GetBranchEndString(type);

            string localpath = MulLanguageUtil.GetLocalAssetsPath(type);
            if (cache_bundle.Count == 0)
            {
                return false;
            }
            foreach (var item in cache_bundle)
            {
                string pt = localpath + item.Value[3]  + "/" + item.Value[0];
                pt = pt.Replace("//", "/");
                if (!File.Exists(pt))
                {
                    return false;
                    //ls_needDownFiles.Add(item.Value);
                }
            }
            return true;
        }

        /// <summary>
        /// 大图使用，过滤掉fui
        /// </summary>
        /// <param name="bundlename"></param>
        /// <returns></returns>
        public string GetBranchBundlePath(string bundlename)
        {
            string endstr = MulLanguageUtil.GetBranchEndString(language);
            string[] arr;
            if (cache_bundle.TryGetValue(bundlename + AppConst.ExtName, out arr))
            {
                if (arr[3] == "fui_tc")
                {
                    return "";
                }
                return MulLanguageUtil.GetLocalAssetsPath(language) + arr[3] + "/" + arr[0];
            }
            return "";
        }

        public string GetBranchFUIBundlePath(string bundlename)
        {
            string endstr = MulLanguageUtil.GetBranchEndString(language);
            string[] arr;
            bundlename = Path.GetFileNameWithoutExtension(bundlename);
            if (cache_bundle.TryGetValue(bundlename.ToLower() + "_" + MulLanguageUtil.GetBranchEndString(language).ToLower() + AppConst.ExtName, out arr))
            {
                return MulLanguageUtil.GetLocalAssetsPath(language) + arr[3] + "/" + arr[0] ;
            }
            return "";
        }

        /// <summary>
        /// fui addpacage调用
        /// </summary>
        public void LoadBundleFromCache(string name)
        {
            name = name.Replace("_fui", "");
            foreach (var item in cache_bundle)
            {
                if (item.Value[0] == name.ToLower() + "_" + MulLanguageUtil.GetBranchEndString(language).ToLower())
                {
                    string path = MulLanguageUtil.GetLocalAssetsPath(language) + item.Value[3] + "/" + item.Value[0];
                    AssetBundle bundle = AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource).LoadAssetBundleFromFile(item.Value[0], path);
                    break;
                }
            }
        }

        public void StartDownloadBranchRes(LanguageType type)
        {
            StartCoroutine(DownLoadFUIBranchRes(type));
        }

        public IEnumerator DownLoadFUIBranchRes(LanguageType type, bool showPanel = true)
        {
            string end_str = MulLanguageUtil.GetBranchEndString(type);
            string path = Util.DataPath + "FuiBranch/" + end_str.ToLower() + "_files.txt";//清单

            string[] files = File.ReadAllLines(path);

            if (showPanel)
            {
                LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");

                if (files.Length > 0)
                {
                    if (luaTable != null)
                    {
                        Util.CallDisposeMethod("LanguageManager", "ShowDownLoadProcess", new object[] { files.Length });
                    }
                }
            }

            for (int i = 0; i < files.Length; i++)
            {
                var arr = files[i].Split('|');

                if (arr[3] == null)
                    arr[3] = "";

                string url = AppConst.BranchUrl + end_str.ToLower() + "/" + arr[3] + "/" + arr[0].ToLower();
                if (string.IsNullOrEmpty(arr[3]))
                {
                    url = AppConst.BranchUrl + end_str.ToLower() + "/" + arr[0].ToLower();
                }

                string localpath = MulLanguageUtil.GetLocalAssetsPath(type) + arr[3] + "/" + arr[0];
                if (File.Exists(localpath))
                {
                    string localMd5 = Util.md5file(localpath);
                    if (localMd5 != arr[1])
                    {
                        File.Delete(localpath);
                        yield return GetGameManager().DownLoadFile(url, localpath);

                        if (showPanel)
                        {
                            LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                            if (luaTable != null)
                            {
                                Util.CallDisposeMethod("LanguageManager", "RefreshDownload", new object[] { Path.GetFileNameWithoutExtension(arr[0]), i });//名称和进度
                            }
                        }
                    }
                }
                else
                {
                    yield return GetGameManager().DownLoadFile(url, localpath);
                    if (showPanel)
                    {
                        LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                        if (luaTable != null)
                        {
                            Util.CallDisposeMethod("LanguageManager", "RefreshDownload", new object[] { Path.GetFileNameWithoutExtension(arr[0]), i });//名称和进度
                        }
                    }
                     
                }
            }

            Util.Log("分支所需资源下载完成，开始切换分支");

            if (showPanel)
            {
                LuaTable luaTable = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua).GetTable("LanguageManager");
                if (luaTable != null)
                {
                    Util.CallDisposeMethod("LanguageManager", "DownloadFinish");
                    luaTable.Dispose();
                }
            }
            
            yield return null;
        }

    }
}
